package org.skatiger.jrove.spring.tags.component;

import java.io.IOException;

import org.skatiger.jrove.JroveException;
import org.skatiger.jrove.ViewContext;
import org.skatiger.jrove.spring.tags.NestedPath;
import org.skatiger.jrove.spring.tags.SpringComponent;
import org.springframework.web.servlet.support.BindStatus;

public class Bind extends SpringComponent {
    public static final String STATUS_VARIABLE_NAME = "status";

    private String path;

    private Boolean ignoreNestedPath;

    private BindStatus status;

    private Object previousPageStatus;

    private Object previousRequestStatus;

    public void setIgnoreNestedPath(boolean ignoreNestedPath) {
        this.ignoreNestedPath = ignoreNestedPath;
    }

    public Boolean isIgnoreNestedPath() {
        return getPropertyValue("ignoreNestedPath", ignoreNestedPath,
                Boolean.FALSE);
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getPath() {
        return getPropertyValue("path", path);
    }

    @Override
    public boolean getRendersChildren() {
        return true;
    }

    @Override
    public void encodeChildren(ViewContext context) throws IOException {
        String resolvedPath = getPath();
        if (!isIgnoreNestedPath()) {
            String nestedPath = (String) context
                    .getAttribute(NestedPath.NESTED_PATH_VARIABLE_NAME);
            // only prepend if not already an absolute path
            if (nestedPath != null
                    && !resolvedPath.startsWith(nestedPath)
                    && !resolvedPath.equals(nestedPath.substring(0,
                            nestedPath.length() - 1))) {
                resolvedPath = nestedPath + resolvedPath;
            }
        }

        try {
            this.status = new BindStatus(getRequestContext(), resolvedPath,
                    isHtmlEscape());
        } catch (IllegalStateException ex) {
            throw new JroveException(ex.getMessage());
        }

        // Save previous status values, for re-exposure at the end of this tag.
        this.previousPageStatus = context.getAttribute(STATUS_VARIABLE_NAME);
        this.previousRequestStatus = context.getAttribute(STATUS_VARIABLE_NAME);

        // Expose this tag's status object as ViewContext attribute,
        // making it available for Jrove EL.
        context.removeAttribute(STATUS_VARIABLE_NAME);
        context.setAttribute(STATUS_VARIABLE_NAME, this.status);

        //-------------------------------------------------------
        // encode children start
        super.encodeChildren(context);
        // encode children end
        //-------------------------------------------------------

        if (this.previousPageStatus != null) {
            context.setAttribute(STATUS_VARIABLE_NAME, this.previousPageStatus);
        }
        if (this.previousRequestStatus != null) {
            context.setAttribute(STATUS_VARIABLE_NAME,
                    this.previousRequestStatus);
        } else {
            context.removeAttribute(STATUS_VARIABLE_NAME);
        }
    }

}
